//
// Created by nilyang on 2022/2/19.
//
#include "include.h"
#include "stl_polymorphic_transform.h"

#if CPP_STANDARD >=  202002L
/// 作者：ll323
/// 链接：https://www.zhihu.com/question/442382012/answer/1732271320
#include <array>
#include <tuple>
#include <algorithm>

/// polymorphic_transform 对给定一组数据，和一组规则，对每一组数据执行规则并输出结果
auto polymorphic_transform(auto &&funcs, auto &&...p) {
    auto remove_head = [](auto &&x) {
        return std::apply([](auto &&, auto &&...t) {
            return std::tuple{std::forward<decltype(t)>(t)...};
        }, std::forward<decltype(x)>(x));
    };
    if constexpr (std::tuple_size_v<std::decay_t<decltype(funcs)>> == 1)
        return std::tuple{std::get<0>(funcs)(std::forward<decltype(p)>(p))...};
    else
        return polymorphic_transform(remove_head(std::forward<decltype(funcs)>(funcs)),
                                     std::get<0>(funcs)(std::forward<decltype(p)>(p))...);
}

/// 多态转换测试
void func_polymophic_transform() {
#if CPP_STANDARD >= CPP_LT_2020
    auto ops = std::tuple{
            [](auto x) {
                for (auto &y: x) y += y;
                return x;
            },
            [](auto x) {
                std::reverse(x.begin(), x.end());
                return x;
            }
    };
    // "xxx"s string::operator ""s()
    using namespace std::string_literals;

    std::cout << "Hello polymorphic_transform:Yes\n";
    std::array ints{1, 2, 3};
    std::array floats{2.71, 3.14};
    std::array strs{"hello"s, "world"s, "?!"s};
    auto[x, y, z] = polymorphic_transform(ops, ints, floats, strs);
    for (auto i: x) {
        std::cout << i << " ";
    }
    std::cout << std::endl;
    for (auto i: y) {
        std::cout << i << " ";
    }
    std::cout << std::endl;
    for (const auto& i: z) {
        std::cout << i << " ";
    }
#endif
}

#endif